package v2;

import java.util.ArrayList;
import java.util.Random;

/**
 * @author bosc & dunoyerd
 * @version 0.1
 * @see
 * @since version 0.1
 */
public class Parcelle {


	// Attributs
	
	/**
	 * La position de la parcelle
	 */
	private Position maPosition;
	
	/**
	 * Le type de la parcelle
	 */
	private TypeParcelle monType;
	
	/**
	 * L'animal présent sur la parcelle
	 */
	private Animaux monAnimal;
	
	/** 
	 * La plante présente sur la parcelle
	 */
	private Vegetaux monVegetal;
	
	/** 
	 * La dépression présente sur la parcelle
	 */
	private Depression maDepr;
	
	/**
	 * L'hygrométrie de la parcelle
	 */
	private int tauxHygro;
	
	// Constructeurs
	
	/**
	 * Méthode qui créer une parcelle à partir de rien
	 */
	public Parcelle()
	{
		this.maPosition = null;
		this.monType = null;
		this.monAnimal = null;
		this.monVegetal = null;
		this.tauxHygro = 0;
		this.maDepr = null;
	}

	// Constructeur
	/**
	 * Méthode qui permet de créer une parcelle avec sa position sur le terrain, son type, son animal, sa plante, sa dépression et son taux d'humidité
	 
	 * @param maPosition
	 * 			la postion de la parcelle
	 * @param monType
	 * 			le type de la parcelle
	 */
	public Parcelle(Position maPosition, TypeParcelle monType)
	{
		this.maPosition = maPosition;
		this.monType = monType;
		this.monAnimal = null;
		this.monVegetal = null;
		this.maDepr = null;
		
		// On met une valeur par defaut...
		Random monRand = new Random();
		this.tauxHygro = monRand.nextInt((monType.maxHygro()+1)-monType.minHygro()) +monType.minHygro();
	}
	
	// constructeur sans animal, sans vegetal mais avec hygro
	/**
	 * Méthode qui permet de créer une parcelle avec sa position sur le terrain, son type et son taux d'humidité
	 
	 * @param maPosition
	 * 			la postion de la parcelle
	 * @param monType
	 * 			le type de la parcelle
	 * @param monHygro
	 * 			le taux d'humidité de la parcelle
	 */
	public Parcelle(int monHygro, Position maPosition, TypeParcelle monType)
	{
		this(maPosition,monType);
		this.tauxHygro = monHygro;
	}
	
	// constructeur avec animal mais pas hygro
	/**
	 * Méthode qui permet de créer une parcelle avec sa position sur le terrain, son type, son animal
	 * 
	 * @param maPosition
	 * 			la postion de la parcelle
	 * @param monType
	 * 			le type de la parcelle
	 * @param monAnimal
	 * 			l'animal présent sur la parcelle
	 */
	public Parcelle(Position maPosition, TypeParcelle monType, Animaux monAnimal)
	{
		this(maPosition,monType);
		this.monAnimal = monAnimal;
	}
	
	// constructeur avec animal mais pas hygro
	/**
	 * Méthode qui permet de créer une parcelle avec sa position sur le terrain, son type, son animal et son taux d'humidité
	 *
	 * @param maPosition
	 * 			la postion de la parcelle
	 * @param monType
	 * 			le type de la parcelle
	 * @param monHygro
	 * 			le taux d'humidité de la parcelle
	 * @param monAnimal
	 * 			l'animal présent sur la parcelle
	 */
	public Parcelle(int monHygro, Position maPosition, TypeParcelle monType, Animaux monAnimal)
	{
		this(maPosition,monType,monAnimal);
		this.tauxHygro = monHygro;
	}
	
	// Constructeur vegetal, sans hygro
	/**
	 * Méthode qui permet de créer une parcelle avec sa position sur le terrain, son type, sa plante
	 * 	 
	 * @param maPosition
	 * 			la postion de la parcelle
	 * @param monType
	 * 			le type de la parcelle
	 * @param monVegetal
	 * 			le vegetal présent sur la parcelle
	 */
	public Parcelle(Position maPosition, TypeParcelle monType, Vegetaux monVegetal)
	{
		this(maPosition,monType);
		this.monVegetal = monVegetal;
	}
	
	// Constructeur vegetal, avec hygro
	/**
	 * Méthode qui permet de créer une parcelle avec sa position sur le terrain, son type, sa plante, et son taux d'humidité
	 
	 * @param maPosition
	 * 			la postion de la parcelle
	 * @param monType
	 * 			le type de la parcelle
	 * @param monHygro
	 * 			le taux d'humidité de la parcelle
	 * @pram monVegetal
	 * 			le végétal présent sur la parcelle
	 */
	public Parcelle(int monHygro, Position maPosition, TypeParcelle monType, Vegetaux monVegetal)
	{
		this(maPosition,monType,monVegetal);
		this.tauxHygro = monHygro;
	}
	
	// Constructeur animal, vegetal, sans hygro
	/**
	 * Méthode qui permet de créer une parcelle avec sa position sur le terrain, son type, son animal, sa plante
	 * 
	 * @param maPosition
	 * 			la postion de la parcelle
	 * @param monType
	 * 			le type de la parcelle
	 * @param monAnimal
	 * 			l'animal présent sur la parcelle
	 * param monVégétal
	 * 			le végétal présent sur la parcelle
	 */
	public Parcelle(Position maPosition, TypeParcelle monType, Animaux monAnimal, Vegetaux monVegetal)
	{
		this(maPosition,monType,monVegetal);
		this.monVegetal = monVegetal;
	}
	
	// Constructeur animal, vegetal, avec hygro
	/**
	 * Méthode qui permet de créer une parcelle avec sa position sur le terrain, son type, son animal, sa plante et son taux d'humidité
	 
	 * @param maPosition
	 * 			la postion de la parcelle
	 * @param monType
	 * 			le type de la parcelle
	 * @param monAnimal
	 * 			l'animal présent sur la parcelle
	 * @param monVégétal
	 * 			le végétal présent sur la parcelle
	 * @param monHydro
	 * 			le taux d'humidité de la parcelle
	 */
	public Parcelle(int monHygro, Position maPosition, TypeParcelle monType, Animaux monAnimal, Vegetaux monVegetal)
	{
		this(maPosition,monType,monAnimal,monVegetal);
		this.tauxHygro = monHygro;
	}
	
	// Accesseurs
	// "Getteurs"

	/**
	 * Retourne le végétal de la parcelle
	 * 
	 * @return monVegetal
	 */
		public Vegetaux obtientVegetal() {
		return monVegetal;
	}
	
	/**
	 * Retourne le taux d'hydrométrie de la parcelle
	 * 
	 * @return tauxHygro
	 */
	public int obtientTauxHygro() {
		return tauxHygro;
	}
	
	/**
	 * Retourne la position de la parcelle
	 * 
	 * @return maPosition
	 */
	public Position obtientMaPosition() {
		return maPosition;
	}
	/**
	 * Retourne le type de parcelle 
	 * 
	 * @return monType
	 */
	public TypeParcelle obtientMonType() {
		return monType;
	}
	
	/**
	 * Retourne l'animal présent sur la parcelle (s'il y en a un)
	 
	 * @return monAnimal
	 */
	public Animaux obtientMonAnimal() {
		return monAnimal;
	}

	public Vegetaux obtientMonVegetal() {
		return monVegetal;
	}
	
	/**
	 * Méthode de savoir si l'entité est une plante
	 * 
	 * @return true si c'est une plante
	 */
	public boolean estPlante()
	{
		if (this.monVegetal == null)
		{
			return false;
		}
		return true;
	}
	
	/**
	 * Méthode de savoir si l'entité est un animal
	 * 
	 * @return true si c'est un animal
	 */
	public boolean estAnimal()
	{
		if (this.monAnimal == null)
		{
			return false;
		}
		return true;
	}
	
	// "Setteurs"

	/**
	 * assigne un animal la parcelle
	 * 
	 * @param monAnimal
	 */
	
	public void assigneMonAnimal(Animaux monAnimal) {
		this.monAnimal = monAnimal;
	}
	/**
	 * assigne un végétal à la parcelle
	 * 
	 * @param monVegetal
	 */
	public void assigneMonVegetal(Vegetaux monVegetal) {
		this.monVegetal = monVegetal;
	}

	/**
	 * assigne une dépression à la parcelle
	 * 
	 * @param maDepression
	 */
	public void assigneMaDepression(Depression maDepression) {
		this.maDepr = maDepression;
	}
	
	/**
	 * @param tauxHygro the tauxHygro to set
	 */
	public void assigneTauxHygro(int tauxHygro) {
		this.tauxHygro = tauxHygro;
	}
	
	// Méthodes
	
	/**
	 * Méthode qyui dit si la parcelle est accesible
	 * 
	 * @return true si la parcelle est accessible, false sinon
	 */
	// utiliser par Animaux.parcellesLibresEtAccess()
	public boolean estAccessible()
	{
		if((this.obtientMonAnimal() == null) && this.obtientMonType().accessible())
		{
			return true;
		}
		return false;
	}
	
	
	/**
	 * Calcule la distance entre 2 parcelle
	 * 
	 * @param maParcelle
	 * 
	 * @return un double qui est la distance entre 2 parcelles
	 */
	// utilisé par Parcelle.plusProcheParcelle()
	public double distanceDeuxParcelles(Parcelle maParcelle)
	{
		return Position.calculDistance(this.obtientMaPosition(), maParcelle.obtientMaPosition());
	}
	
	/**
	 * Calcule quelle est la plus proche parcelle parmis toutes celles de la liste
	 * 
	 * @param mesParcelles
	 * 
	 * @return la parcelle la plus proche
	 */
	// utilisé par Animaux deplParcItineraireVersParc(...)
	public Parcelle plusProcheParcelle(ArrayList<Parcelle> mesParcelles){
		if (!mesParcelles.isEmpty())
		{
			Parcelle maParcelleTemp = mesParcelles.get(0);
			double distanceMin = this.distanceDeuxParcelles(maParcelleTemp);
			
			for (int i=1;i<mesParcelles.size();i++)
			{
				double distTemp = this.distanceDeuxParcelles(mesParcelles.get(i));
				if (distTemp<distanceMin)
				{
					distanceMin=distTemp;
					maParcelleTemp = mesParcelles.get(i);
				}
			}
			return maParcelleTemp;
		}
		else
		{
			return null;
		}
	}
	
	/**
	 * 
	 */
	public String toString()
	{
		String myString = new String("");
		myString+=" position: "+maPosition.toString();
		myString+=" mon type: "+monType.nomType();
		myString+=" mon taux Hygro: "+tauxHygro;
		if (monAnimal != null)
		{
			myString+=" mon animal: "+monAnimal.toString();
		}
		if (monVegetal != null)
		{
			myString+=" mon végetal: "+monVegetal.toString();
		}
		if (maDepr != null)
		{
			myString+=" ma depression"+maDepr.toString();
		}	
		return myString;
	}
}
